package com.toonly.tests;

import com.sun.istack.internal.NotNull;

import java.lang.annotation.*;
import java.lang.reflect.Method;
import java.util.Arrays;

public class AnnotationTests {

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD})
    private @interface AnnoA {
        String test();
        String[] arr() default {};
    }

    private interface ClassA {
        @AnnoA(test = "abc", arr = {"a", "b"})
        void methodA();
    }

    private static class ClassAImpl implements ClassA {
        @NotNull
        public void methodA() {

        }
    }

    public static void main(String[] args) {

        Method methodA = null;
        try {
            methodA = ClassAImpl.class.getMethod("methodA");
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        System.out.println(methodA);

        Annotation[] declaredAnnotations = methodA.getDeclaredAnnotations();
        System.out.println(declaredAnnotations.length);

        System.out.println(Arrays.toString(methodA.getAnnotations()));

        Class<?>[] interfaces = ClassAImpl.class.getInterfaces();
        System.out.println(interfaces.length);

        Method methodAI = null;
        try {
            methodAI = interfaces[0].getMethod(methodA.getName());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        System.out.println(methodAI);

        Annotation[] declaredAnnos = methodAI.getDeclaredAnnotations();
        System.out.println(declaredAnnos.length);

        Annotation[] annotations = methodAI.getAnnotations();
        System.out.println(annotations.length);

        System.out.println(declaredAnnos[0].annotationType());

//        a no
        String[] arrays = getAnnotation(ClassAImpl.class, AnnoA.class, "methodA").arr();
        System.out.println(Arrays.toString(arrays));

    }

    private static <T extends Annotation> T getAnnotation(Class<?> clazz, Class<T> annoClazz, String methodName) {
        Method method = null;
        try {
            method = clazz.getDeclaredMethod(methodName);
        } catch (NoSuchMethodException e) {
            return null;
        }
        Annotation annotation = method.getAnnotation(annoClazz);
        if (null == annotation) {
            Class<?>[] interfaces = clazz.getInterfaces();
            if (interfaces.length > 0) {
                return getAnnotation(interfaces[0], annoClazz, methodName);
            }
            return null;
        }
        return (T) annotation;
    }

}
